package com.rizhov.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;

import com.rizhov.enumerations.GraphOrientation;
import com.rizhov.graph.Graph;

public class LayoutPanelPopupMenu extends JPopupMenu {

    Graph graph = Graph.getInstance();
    LayoutPanel lp = LayoutPanel.getInstance();

    public LayoutPanelPopupMenu(boolean addEnabled, boolean deleteEnabled, boolean vertexEdit,
	    boolean edgeEdit, boolean edgeRemove) {
	super();
	JMenuItem addElement = new JMenuItem("Add new vertex");
	addElement.addActionListener(new ActionListener() {

	    @Override
	    public synchronized void actionPerformed(ActionEvent e) {
		String dataStr;
		out_mark: if ((dataStr = JOptionPane.showInputDialog("Enter vertex data")) != null) {
		    for (int i = 0; i < lp.ellipseArr.size(); i++) {
			if (dataStr.equals(lp.ellipseArr.get(i).getData())) {
			    JOptionPane.showMessageDialog(null, "That value is already exist in graph!",
				    "Error!", JOptionPane.ERROR_MESSAGE);
			    break out_mark;
			}
		    }
		    lp.ellipseArr.add(new GraphVertexEllipse(lp.popupX, lp.popupY, LayoutPanel.DEFAULT_SIDE,
			    LayoutPanel.DEFAULT_SIDE, dataStr));
		    graph.addVertex(dataStr);
		    System.out.println(1);
		    lp.repaint();
		}
	    }
	});
	addElement.setEnabled(addEnabled);
	this.add(addElement);

	JMenuItem deleteElement = new JMenuItem("Delete vertex");
	deleteElement.addActionListener(new ActionListener() {

	    @Override
	    public synchronized void actionPerformed(ActionEvent e) {
		if (JOptionPane.showConfirmDialog(null, "Do you really want to delete this vertex?",
			"Delete dialog", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
		    GraphVertexEllipse ellipse = lp.getEllipseContains(lp.popupX, lp.popupY);
		    graph.removeVertex(ellipse.getData());
		    lp.indexArr = null;
		    lp.ellipseArr.remove(ellipse);
		    lp.repaint();
		}
	    }

	});
	deleteElement.setEnabled(deleteEnabled);
	this.add(deleteElement);

	JMenuItem editVertex = new JMenuItem("Edit vertex");
	editVertex.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		String dataStr;
		out_mark: if ((dataStr = JOptionPane.showInputDialog("Enter new vertex data")) != null) {
		    for (int i = 0; i < lp.ellipseArr.size(); i++) {
			if (dataStr.equals(lp.ellipseArr.get(i).getData())) {
			    JOptionPane.showMessageDialog(null, "That value is already exist in graph!",
				    "Error!", JOptionPane.ERROR_MESSAGE);
			    break out_mark;
			}
		    }
		    graph.setVertexData(dataStr, lp.ellipseForPopup.getData());
		    lp.ellipseForPopup.setData(dataStr);
		    lp.repaint();
		}
	    }
	});
	editVertex.setEnabled(vertexEdit);
	this.add(editVertex);

	JMenuItem editEdge = new JMenuItem("Edit edge");
	editEdge.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		//
		if (graph.isEdgeExist(lp.sparkingEdge.startVertexIndex, lp.sparkingEdge.endVertexIndex)
			&& graph.isEdgeExist(lp.sparkingEdge.endVertexIndex, lp.sparkingEdge.startVertexIndex)) {
		    Object[] options = { "Blue edge", "Red edge" };
		    int n = JOptionPane.showOptionDialog(null, "What kind of edge do you want to edit?",
			    "Color option pane", JOptionPane.YES_NO_CANCEL_OPTION,
			    JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
		    if (n == 0) {
			// BLUE
			int fromIndex = lp.sparkingEdge.startVertexIndex < lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			int toIndex = lp.sparkingEdge.startVertexIndex > lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			TwoFieldOptionPane tfop = new TwoFieldOptionPane();
			tfop.setBounds(290, 150, tfop.getWidth(), tfop.getHeight());
			tfop.setVisible(true);
			if (tfop.result == JOptionPane.OK_OPTION) {
			    graph.setEdgeData(fromIndex, toIndex, tfop.messageOne);
			    graph.setEdgeWeight(fromIndex, toIndex, tfop.messageTwo);
			    lp.sparkingEdge.edgeData = tfop.messageTwo;			    
			    lp.sparkingEdge.edgeWeight = tfop.messageOne;
			}
		    } else if (n == 1) {
			// RED
			int fromIndex = lp.sparkingEdge.startVertexIndex > lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			int toIndex = lp.sparkingEdge.startVertexIndex < lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;

			TwoFieldOptionPane tfop = new TwoFieldOptionPane();
			tfop.setBounds(290, 150, tfop.getWidth(), tfop.getHeight());
			tfop.setVisible(true);
			if (tfop.result == JOptionPane.OK_OPTION) {
			    graph.setEdgeData(fromIndex, toIndex, tfop.messageOne);
			    graph.setEdgeWeight(fromIndex, toIndex, tfop.messageTwo);
			    lp.sparkingEdge.edgeData = tfop.messageOne;
			    lp.sparkingEdge.edgeWeight = tfop.messageTwo;
			}
		    }

		} else {
		    TwoFieldOptionPane tfop = new TwoFieldOptionPane();
		    tfop.setBounds(290, 150, tfop.getWidth(), tfop.getHeight());
		    tfop.setVisible(true);
		    if (tfop.result == JOptionPane.OK_OPTION) {
			graph.setEdgeData(lp.sparkingEdge.startVertexIndex, lp.sparkingEdge.endVertexIndex,
				tfop.messageOne);
			graph.setEdgeWeight(lp.sparkingEdge.startVertexIndex, lp.sparkingEdge.endVertexIndex,
				tfop.messageTwo);
			lp.sparkingEdge.edgeData = tfop.messageOne;
			lp.sparkingEdge.edgeWeight = tfop.messageTwo;
		    }
		}
		//
		lp.repaint();
	    }
	});
	editEdge.setEnabled(edgeEdit);
	this.add(editEdge);

	JMenuItem removeEdge = new JMenuItem("Remove edge");
	removeEdge.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		if (graph.isEdgeExist(lp.sparkingEdge.startVertexIndex, lp.sparkingEdge.endVertexIndex)
			&& graph.isEdgeExist(lp.sparkingEdge.endVertexIndex, lp.sparkingEdge.startVertexIndex) && graph.getGraphDirectionType() == GraphOrientation.ORIENTED_GRAPH) {
		    Object[] options = { "Blue edge", "Red edge" };
		    int n = JOptionPane.showOptionDialog(null, "What kind of edge do you want to remove?",
			    "Color option pane", JOptionPane.YES_NO_CANCEL_OPTION,
			    JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
		    if (n == 0) {
			// BLUE
			int fromIndex = lp.sparkingEdge.startVertexIndex < lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			int toIndex = lp.sparkingEdge.startVertexIndex > lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			if (JOptionPane.showConfirmDialog(null, "Do you really want to remove this edge?",
				"Delete dialog", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
			    graph.removeEdge(fromIndex, toIndex);
			}
		    } else if (n == 1) {
			// RED
			int fromIndex = lp.sparkingEdge.startVertexIndex > lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;
			int toIndex = lp.sparkingEdge.startVertexIndex < lp.sparkingEdge.endVertexIndex ? lp.sparkingEdge.startVertexIndex
				: lp.sparkingEdge.endVertexIndex;

			if (JOptionPane.showConfirmDialog(null, "Do you really want to remove this edge?",
				"Delete dialog", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
			    graph.removeEdge(fromIndex, toIndex);
			}
		    }

		} else if (JOptionPane.showConfirmDialog(null, "Do you really want to remove this edge?",
			"Delete dialog", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
		    graph.removeEdge(lp.sparkingEdge.startVertexIndex, lp.sparkingEdge.endVertexIndex);
		}
		lp.repaint();
	    }
	});
	editEdge.setEnabled(edgeRemove);
	this.add(removeEdge);
    }
}
